package com.catsic.practice.service;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.catsic.practice.entity.LeaveApplication;
import com.catsic.practice.entity.Result;
import com.catsic.practice.entity.TaskDTO;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceBuilder;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: zhangzf
 * @CreateTime: 2025-10-24  14:53
 * @Description: 请假流程服务类
 */
@Service
public class LeaveProcessService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;


    /**
     * 启动请假流程
     */
    public Result startLeaveProcess(LeaveApplication leaveApplication){
        Map<String, Object> variables = new HashMap<>();
        variables.put("applicant", leaveApplication.getApplicant());
        variables.put("leaveDays", leaveApplication.getLeaveDays());
        variables.put("reason", leaveApplication.getReason());
        variables.put("instructorAssignee", leaveApplication.getInstructorAssignee());
        variables.put("headTeacherAssignee", leaveApplication.getHeadTeacherAssignee());
        variables.put("directorAssignee", leaveApplication.getDirectorAssignee());
        ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
        ProcessInstance processInstance = processInstanceBuilder
                .processDefinitionKey("threeLevelLeaveProcess")
                .variables(variables)
                .businessKey(leaveApplication.getId())
                .start();
        return Result.success(processInstance.getId());
    }

    /**
     * 获取用户任务列表
     */
    public List<TaskDTO> getUserTasks(String assignee){
        List<Task> taskList = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .orderByTaskCreateTime()
                .desc()
                .list();
        return taskList.stream()
                .map(TaskDTO::fromTask)
                .collect(Collectors.toList());
    }

    /**
     * 获取任务详情
     */
    public Task getTaskById(String taskId) {
        return taskService.createTaskQuery()
                .taskId(taskId)
                .singleResult();
    }

    /**
     * 审批任务
     */
    public Result completeTask(String taskId, String decision, String comment, String nextAssignee){
        Map<String, Object> variables = new HashMap<>();

        Task task = getTaskById(taskId);
        if (task == null) {
            throw new RuntimeException("任务不存在: " + taskId);
        }

        String taskDefinitionKey = task.getTaskDefinitionKey();

        // 设置统一的决策变量（简化EL表达式）
        variables.put("decision", decision);
        variables.put("comment", comment);

        // 根据当前任务设置下一级审批人
        if (nextAssignee != null && !nextAssignee.isEmpty()) {
            if ("instructorApproval".equals(taskDefinitionKey)) {
                variables.put("headTeacherAssignee", nextAssignee);
            } else if ("headTeacherApproval".equals(taskDefinitionKey)) {
                variables.put("directorAssignee", nextAssignee);
            }
        }

        // 记录任务特定的决策信息（用于历史记录）
        variables.put(taskDefinitionKey + "Decision", decision);
        variables.put(taskDefinitionKey + "Comment", comment);

        // 完成任务
        taskService.complete(taskId, variables);

        // 如果是回退操作，需要设置回退后的任务处理人
        if ("back".equals(decision)) {
            handleBackOperation(task, variables);
        }
        return Result.success("审批成功");
    }

    /**
     * 处理回退操作
     */
    private void handleBackOperation(Task currentTask, Map<String, Object> variables) {
        String processInstanceId = currentTask.getProcessInstanceId();

        // 获取当前流程实例的所有任务
        List<Task> activeTasks = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .list();

        for (Task task : activeTasks) {
            String taskDefKey = task.getTaskDefinitionKey();

            // 根据当前任务决定回退到哪个节点
            if ("headTeacherApproval".equals(currentTask.getTaskDefinitionKey())) {
                // 班主任回退到辅导员
                if ("instructorApproval".equals(taskDefKey)) {
                    // 可以在这里重新分配任务处理人
                    taskService.setAssignee(task.getId(), (String) variables.get("instructorAssignee"));
                }
            } else if ("directorApproval".equals(currentTask.getTaskDefinitionKey())) {
                // 教导主任回退到班主任
                if ("headTeacherApproval".equals(taskDefKey)) {
                    taskService.setAssignee(task.getId(), (String) variables.get("headTeacherAssignee"));
                }
            }
        }
    }

    /**
     * 获取流程状态
     */
    public Result getProcessStatus(String processInstanceId){
        HistoricProcessInstance processInstance = historyService
                .createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        if(processInstance != null){
            if(processInstance.getEndTime() != null){
                return Result.success("COMPLETED");
            }else {
                return Result.success("ACTIVE");
            }
        }
        return Result.error("流程不存在");
    }
}
